컴퓨터과학
어셈블리_03_명령어 집합과 제어 흐름
작성자 : Heehyeon Yoo|2025-10-09
# Assembly# Instruction# Control Flow# JCC
어셈블리어에는 if, while 같은 구조화된 제어문이 존재하지 않는다. 대신 비교(Compare)와 점프(Jump) 명령어의 조합을 통해 프로그램의 흐름을 제어한다.
1. 기본 명령어
가장 빈번하게 사용되는 데이터 이동 및 연산 명령어다.
- MOV A, B: B의 값을 A로 복사한다.
- ADD / SUB: 덧셈 및 뺄셈을 수행한다.
- INC / DEC: 값을 1 증가시키거나 감소시킨다.
- LEA(Load Effective Address): 메모리 참조가 아닌, 주소값 자체의 연산을 수행한다. 포인터 연산이나 간단한 산술 연산에 최적화되어 있다.(
MOV는 주소 안의 값을 가져오지만,LEA는 주소 그 자체를 가져온다)
2. 분기문의 원리: CMP와 JMP
조건문은 CMP 명령어로 플래그(Flag)를 설정하고, Jcc 명령어로 플래그 상태를 확인하여 분기하는 2단계 과정을 거친다.
(1) 비교: CMP(Compare)
cmp rax, rbx
두 값의 차이(rax - rbx)를 계산한다. 결과값은 저장하지 않고, 대신 RFLAGS 레지스터의 상태 비트(ZF, SF 등)를 갱신한다.
- ZF (Zero Flag): 결과가 0이면(두 값이 같으면) 1로 설정된다.
- SF (Sign Flag): 결과가 음수면 1로 설정된다.
Note: TEST 명령어와의 차이
리버싱을 하다 보면CMP대신TEST명령어가 자주 보인다. (예:test rax, rax)
CMP는 뺄셈 연산(-)을 통해 차이를 확인하지만,TEST는 논리곱(AND) 연산을 수행한다. 주로 "값이 0인지 아닌지" 또는 "NULL 포인터 체크"를 할 때CMP보다 효율적이라서 자주 사용된다.
(2) 분기: Jcc(Jump Condition)
플래그 상태에 따라 실행 흐름을 변경한다.
| 명령어 | 의미 | 조건 |
|---|---|---|
| JE | Jump if Equal | 값이 같을 때 (ZF=1) |
| JNE | Jump if Not Equal | 값이 다를 때 (ZF=0) |
| JG | Jump if Greater | 클 때 |
| JL | Jump if Less | 작을 때 |
3. If-Else 구현 패턴
고급 언어의 구조가 어셈블리어로 변환되면 다음과 같은 형태가 된다.
cmp rax, 10
je is_ok ; 조건 만족 시 점프
; [Else 블록]
call fail
jmp finish ; 필수: 여기서 점프하지 않으면 아래 코드로 흘러내림(Fall-through)
is_ok:
; [If 블록]
call ok
finish:
; 종료
Else 블록 끝에 무조건 분기(JMP)를 넣지 않으면, 의도치 않게 Is_ok 블록까지 실행되는 Fall-through 오류가 발생하므로 주의가 필요하다.